package com.itheima.aop;

import lombok.extern.slf4j.Slf4j;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.*;
import org.springframework.stereotype.Component;

@Component
//@Aspect
@Slf4j
public class Notification {
    //抽取公共的切入点表达式
    @Pointcut("execution(* com.itheima.service.impl.DeptServiceImpl.*(..))")
    public void pointcut() {}

    //前置通知，此注解标注的通知方法在目标方法前被执行
    @Before("pointcut()")//匹配DeptServiceImpl里的所有方法
    public void noticeBefore(){
        log.info("通知类型：before...");
    }

    //后置通知，此注解标注的通知方法在目标方法后被执行，无论是否有异常都会执行
    @After("pointcut()")
    public void noticeAfter(){
        log.info("通知类型：after...");
    }

    //环绕通知，此注解标注的通知方法在目标方法前、后都被执行
    @Around("pointcut()")
    public Object noticeAround(ProceedingJoinPoint proceedingJoinPoint) throws Throwable{

        log.info("环绕通知：around before ...");
        Object result = proceedingJoinPoint.proceed();
        log.info("环绕通知：around after ...");

        return result;
    }

    //返回后通知，此注解标注的通知方法在目标方法后被执行，有异常不会执行
    @AfterReturning("pointcut()")
    public void noticeReturn(){
        log.info("后置通知：afterReturning ...");
    }

    //异常通知（程序在出现异常的情况下，执行的后置通知）
    @AfterThrowing("pointcut()")
    public void noticeThrow(){
        log.info("异常通知：afterThrowing ...");
    }
}
